package com.z.ssmdemo.log.factory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author haonan.zhang
 */
public class Slif4JELoggerImpl implements ELogger {

    private static Class< ? >  clazz = null;

    private final static String INIT_INDEX = "0";
    /**
     * 各类Logger缓存
     */
    private  static final Map<Object, Logger> LOG_CACHE_POOL = new ConcurrentHashMap<>(300);

    public Slif4JELoggerImpl() {
    }

    public Slif4JELoggerImpl(Class< ? >  clazz) {
        Slif4JELoggerImpl.clazz = clazz;
    }
    /**
     * 获取调用类的logger
     */
    private static Logger getLogger() {
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        AtomicReference<String> className = new AtomicReference<>(INIT_INDEX);
        Arrays.stream(stackTrace).forEach(item ->{
            if (clazz.getName().equals(item.getClassName())) {
                String[] split = item.getClassName().split("\\.");
                className.compareAndSet("0",split[split.length - 1]);
            }
        });
        if (INIT_INDEX.equals(className.get())){
            throw new RuntimeException("这个bug是因为你调用log是传入的类型和当前线程的类型不一样。");
        }
        return getLogger(className.get());
    }

    private static Logger getLogger(String loggerName) {
        if (LOG_CACHE_POOL.get(loggerName) != null) {
            return LOG_CACHE_POOL.get(loggerName);
        }
        Logger logger = LoggerFactory.getLogger(loggerName);
        LOG_CACHE_POOL.put(loggerName, logger);
        return logger;
    }

    @Override
    public void info(String message, Throwable t) {
        if (getLogger().isInfoEnabled()) {
            getLogger().info(message, t);
        }
    }
    @Override
    public void info(String message) {
        if (getLogger().isInfoEnabled()) {
            getLogger().info(message);
        }
    }
    @Override
    public  void info(String format, Object... arguments) {
        if (getLogger().isInfoEnabled()) {
            getLogger().info(format, arguments);
        }
    }
    @Override
    public  void info(String format, Object arg1, Object arg2) {
        if (getLogger().isInfoEnabled()) {
            getLogger().info(format, arg1, arg2);
        }
    }
    @Override
    public  void error(String message) {
        if (getLogger().isErrorEnabled()) {
            getLogger().error(message);
        }
    }
    @Override
    public  void error(String format, Object arg1, Object arg2) {
        if (getLogger().isErrorEnabled()) {
            getLogger().error(format, arg1, arg2);
        }
    }
    @Override
    public  void error(String format, Object... arguments) {
        if (getLogger().isErrorEnabled()) {
            getLogger().error(format, arguments);
        }
    }
    @Override
    public  void error(String message, Throwable t) {
        if (getLogger().isErrorEnabled()) {
            getLogger().error(message, t);
        }
    }

    /**
     * debug level
     *
     * @param message
     * @param t
     */
    @Override
    public  void debug(String message, Throwable t) {
        getLogger().debug(message, t);
    }

    /**
     * warn level
     *
     * @param message
     * @param t
     */
    @Override
    public  void warn(String message, Throwable t) {
        getLogger().warn(message, t);
    }

    /**
     * debug level
     *
     * @param message
     */
    @Override
    public  void debug(String message) {
        getLogger().debug(message);
    }

    /**
     * warn level
     *
     * @param message
     */
    @Override
    public  void warn(String message) {
        getLogger().warn(message);
    }
}
